/*
自己选择的路 ,跪着也要走完。朋友们 , 虽然这个世界日益浮躁起来,只
要能够为了当时纯粹的梦想和感动坚持努力下去 , 不管其它人怎么样,我
们也能够保持自己的本色走下去。
To the world , you will be a person , but to a person , you
will be the world .                               ——AKPower
*/
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
const ll maxn = 1e6 + 100;
ll fa[maxn], son[maxn], dep[maxn], siz[maxn], dfn[maxn], rnk[maxn], top[maxn];
ll df_cnt;
ll n, m, R;

struct node
{
    ll l, r, sum, maxx;
} a[maxn * 4];
struct edge
{
    ll y, next_s;
} e[maxn * 2];
ll head[maxn], cnt;
void init()
{
    memset(head, -1, sizeof(head));
    cnt = 0;
    df_cnt = 0;
}
ll val[maxn];

void add(ll x, ll y)
{
    e[cnt].y = y;
    e[cnt].next_s = head[x];
    head[x] = cnt++;
    return;
}

void build(ll k, ll l, ll r)
{
    a[k].l = l;
    a[k].r = r;
    if (l == r)
    {
        // cout << "val=" << val[rnk[l]] << endl;
        a[k].sum = val[rnk[l]];
        a[k].maxx = val[rnk[l]];
        return;
    }
    ll mid = (l + r) >> 1;
    build(k << 1, l, mid);
    build(k << 1 | 1, mid + 1, r);
    a[k].sum = a[k << 1].sum + a[k << 1 | 1].sum;
    a[k].maxx = max(a[k << 1].maxx, a[k << 1 | 1].maxx);
    // cout << "a[k].maxx=" << a[k].maxx << endl;
    return;
}

void update(ll k, ll pos, ll x)
{
    if (a[k].l == a[k].r)
    {
        val[rnk[pos]] = x;
        a[k].sum = val[rnk[pos]];
        a[k].maxx = val[rnk[pos]];
        return;
    }
    ll mid = (a[k].l + a[k].r) >> 1;
    if (pos <= mid)
    {
        update(k << 1, pos, x);
    }
    else
        update(k << 1 | 1, pos, x);
    a[k].sum = a[k << 1].sum + a[k << 1 | 1].sum;
    a[k].maxx = max(a[k << 1].maxx, a[k << 1 | 1].maxx);
    return;
}

void dfs1(ll u)
{
    son[u] = -1;
    siz[u] = 1;
    for (ll i = head[u]; i != -1; i = e[i].next_s)
    {
        ll v = e[i].y;
        if (dep[v] || v == fa[u])
            continue;
        dep[v] = dep[u] + 1;
        fa[v] = u;
        dfs1(v);
        siz[u] += siz[v];
        if (son[u] == -1 || siz[son[u]] < siz[v])
            son[u] = v;
    }
    return;
}
void dfs2(ll u, ll f)
{
    top[u] = f;
    dfn[u] = ++df_cnt;
    rnk[df_cnt] = u;
    if (son[u] == -1)
        return;
    dfs2(son[u], f);
    for (ll i = head[u]; i != -1; i = e[i].next_s)
    {
        ll v = e[i].y;
        if (v == fa[u] || v == son[u])
            continue;
        dfs2(v, v);
    }
    return;
}
ll getsum(ll k, ll l, ll r)
{
    if (a[k].l >= l && a[k].r <= r)
    {
        return a[k].sum;
    }
    ll mid = (a[k].l + a[k].r) >> 1;
    if (r <= mid)
    {
        return getsum(k << 1, l, r);
    }
    if (l > mid)
    {
        return getsum(k << 1 | 1, l, r);
    }
    return getsum(k << 1, l, mid) + getsum(k << 1 | 1, mid + 1, r);
}

ll getmax(ll k, ll l, ll r)
{
    if (a[k].l >= l && a[k].r <= r)
    {
        return a[k].maxx;
    }
    ll mid = (a[k].l + a[k].r) >> 1;
    if (r <= mid)
    {
        return getmax(k << 1, l, r);
    }
    if (l > mid)
    {
        return getmax(k << 1 | 1, l, r);
    }
    return max(getmax(k << 1, l, mid), getmax(k << 1 | 1, mid + 1, r));
}

ll find_sum(ll x, ll y)
{
    ll sum = 0;
    while (top[x] != top[y])
    {
        if (dep[top[x]] > dep[top[y]])
        {
            sum += getsum(1, dfn[top[x]], dfn[x]);
            x = fa[top[x]];
        }
        else
        {
            sum += getsum(1, dfn[top[y]], dfn[y]);
            y = fa[top[y]];
        }
    }
    if (dep[x] > dep[y])
    {
        sum += getsum(1, dfn[y], dfn[x]);
    }
    else
        sum += getsum(1, dfn[x], dfn[y]);
    return sum;
}

ll find_max(ll x, ll y)
{
    ll sum = -30000;
    while (top[x] != top[y])
    {
        if (dep[top[x]] > dep[top[y]])
        {
            sum = max(getmax(1, dfn[top[x]], dfn[x]), sum);
            x = fa[top[x]];
        }
        else
        {
            sum = max(sum, getmax(1, dfn[top[y]], dfn[y]));
            y = fa[top[y]];
        }
    }
    if (dep[x] > dep[y])
    {
        sum = max(sum, getmax(1, dfn[y], dfn[x]));
    }
    else
        sum = max(sum, getmax(1, dfn[x], dfn[y]));
    return sum;
}

int main()
{
    IOS;
    init();
    cin >> n;
    ll x, y;
    for (ll i = 1; i <= n - 1; i++)
    {
        cin >> x >> y;
        add(x, y);
        add(y, x);
    }
    for (ll i = 1; i <= n; i++)
    {
        cin >> val[i];
    }
    //建立重链剖分
    dfs1(1);
    dfs2(1, 1);
    build(1, 1, n);
    cin >> m;
    string flag;
    for (ll i = 1; i <= m; i++)
    {
        cin >> flag >> x >> y;
        if (flag == "CHANGE")
        {
            update(1, dfn[x], y);
        }
        else if (flag == "QSUM")
        {
            cout << find_sum(x, y) << endl;
        }
        else
        {
            cout << find_max(x, y) << endl;
        }
    }
    getchar();
    getchar();
    return 0;
}
